package archer.framework.common.repository.support.ebean.factory;

import archer.framework.common.repository.support.ebean.StringIdGenerator;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.ServerConfig;
import org.avaje.agentloader.AgentLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * EbeanServer FactoryBean
 *
 * @author christ
 * @date 2016/4/21
 */
public class EbeanServerFactoryBean implements InitializingBean, FactoryBean {

    private static Logger logger = LoggerFactory.getLogger(EbeanServerFactoryBean.class);

    @Autowired
    protected ServerConfig config;

    /**
     * 需要enhance的package多个之间用逗号隔开
     */
    protected String packages;

    /**
     * 是否需要在启动的时候做enhance
     */
    private boolean enhanceOnStart = true;


    private EbeanServer server;

    @Override
    public Object getObject() throws Exception {

        return server;
    }

    @Override
    public Class<?> getObjectType() {

        return EbeanServer.class;
    }

    @Override
    public boolean isSingleton() {

        return true;
    }

    protected EbeanServer createEbeanServer() {

        if (config == null) {

            throw new IllegalStateException("ServerConfig bean must be config first");
        }

        // register id generator
        config.add(new StringIdGenerator());

        return EbeanServerFactory.create(config);
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        if (enhanceOnStart) {

            String args = "debug=1;packages=archer.*," + getPackages();

            if (!AgentLoader.loadAgentFromClasspath("avaje-ebeanorm-agent", args)) {

                logger.info("avaje-ebeanorm-agent not found in classpath - not dynamically loaded");
            }
        }

        server = createEbeanServer();
    }

    public ServerConfig getConfig() {
        return config;
    }

    public EbeanServerFactoryBean setConfig(ServerConfig config) {
        this.config = config;
        return this;
    }

    public String getPackages() {
        return packages;
    }

    public EbeanServerFactoryBean setPackages(String packages) {
        this.packages = packages;
        return this;
    }

    public boolean isEnhanceOnStart() {
        return enhanceOnStart;
    }

    public EbeanServerFactoryBean setEnhanceOnStart(boolean enhanceOnStart) {
        this.enhanceOnStart = enhanceOnStart;
        return this;
    }
}
